package com.websocket.hander;

import org.springframework.lang.Nullable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class InterceptorRegistry {

    private final List<InterceptorRegistration> registrations = new ArrayList<>();

    public InterceptorRegistration addInterceptor(HandlerInterceptor interceptor) {
        InterceptorRegistration registration = new InterceptorRegistration(interceptor);
        registrations.add(registration);
        return registration;
    }

    public List<HandlerInterceptor> getInterceptors(String path) {
        return registrations.stream().filter(registration -> {
            if (registration.includePatterns == null) return true;
            for (String includePattern : registration.includePatterns) {
                if (MatchPath.match(includePattern, path)) {
                    return true;
                }
            }
            return false;
        }).filter(registration -> {
            if (registration.excludePatterns == null) return true;
            for (String excludePattern : registration.excludePatterns) {
                if (MatchPath.match(excludePattern, path)) {
                    return false;
                }
            }
            return true;
        }).map(InterceptorRegistration::getInterceptor).toList();
    }

    public static class InterceptorRegistration {
        private final HandlerInterceptor interceptor;

        @Nullable
        private List<String> includePatterns;

        @Nullable
        private List<String> excludePatterns;

        public InterceptorRegistration(HandlerInterceptor interceptor) {
            this.interceptor = interceptor;
        }

        public HandlerInterceptor getInterceptor() {
            return interceptor;
        }

        @Nullable
        public List<String> getIncludePatterns() {
            return includePatterns;
        }

        /**
         * 可用匹配符：[ **, * ]
         * <p>暂时只支持以目录为单位的匹配
         * <p>** 表示可以匹配 0 个或多个目录
         * <p>*  表示必须匹配 1 个目录
         *
         * <p>例如"/**", "/api/**", "/**<t>/sub", "/api/*<t>/batch/**",
         */
        public InterceptorRegistration addPathPatterns(String... patterns) {
            return this.addPathPatterns(Arrays.asList(patterns));
        }

        /**
         * 可用匹配符：[ **, * ]
         * <p>暂时只支持以目录为单位的匹配
         * <p>** 表示可以匹配 0 个或多个目录
         * <p>*  表示必须匹配 1 个目录
         *
         * <p>例如"/**", "/api/**", "/**<t>/sub", "/api/*<t>/batch/**",
         */
        public InterceptorRegistration addPathPatterns(List<String> patterns) {
            this.includePatterns = patterns;
            return this;
        }

        @Nullable
        public List<String> getExcludePatterns() {
            return excludePatterns;
        }

        /**
         * 可用匹配符：[ **, * ]
         * <p>暂时只支持以目录为单位的匹配
         * <p>** 表示可以匹配 0 个或多个目录
         * <p>*  表示必须匹配 1 个目录
         *
         * <p>例如"/**", "/api/**", "/**<t>/sub", "/api/*<t>/batch/**",
         */
        public InterceptorRegistration excludePathPatterns(String... excludePatterns) {
            return this.excludePathPatterns(Arrays.asList(excludePatterns));
        }

        /**
         * 可用匹配符：[ **, * ]
         * <p>暂时只支持以目录为单位的匹配
         * <p>** 表示可以匹配 0 个或多个目录
         * <p>*  表示必须匹配 1 个目录
         *
         * <p>例如"/**", "/api/**", "/**<t>/sub", "/api/*<t>/batch/**",
         */
        public InterceptorRegistration excludePathPatterns(List<String> excludePatterns) {
            this.excludePatterns = excludePatterns;
            return this;
        }
    }
}
